#include "wasapi_loopback_capture_simple.h"
#include <QDebug>
#include <QDir>
#include <QCoreApplication>

// 链接必要的库
#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "oleaut32.lib")
#pragma comment(lib, "avrt.lib")

WasapiLoopbackCaptureSimple::WasapiLoopbackCaptureSimple(QObject *parent)
    : QObject(parent)
    , m_deviceEnumerator(nullptr)
    , m_audioDevice(nullptr)
    , m_audioClient(nullptr)
    , m_captureClient(nullptr)
    , m_waveFormat(nullptr)
    , m_bufferFrameCount(0)
    , m_captureTimer(nullptr)
    , m_isCapturing(false)
    , m_wasapiInitialized(false)
    , m_transmitter(nullptr)
    , m_transmissionEnabled(false)
    , m_transmissionHost("localhost")
    , m_transmissionPort(8766)
{
    m_captureTimer = new QTimer(this);
    connect(m_captureTimer, &QTimer::timeout, this, &WasapiLoopbackCaptureSimple::onCaptureTimer);
    
    // 在构造函数中不初始化COM，等到实际使用时再初始化
    qDebug() << "WASAPI捕获器已创建，等待初始化...";

    // 初始化音频传输器
    m_transmitter = new AudioTransmitter(this);
    
    // 连接传输器信号
    connect(m_transmitter, &AudioTransmitter::transmissionStatusChanged,
            this, &WasapiLoopbackCaptureSimple::onTransmissionStatusChanged);
    connect(m_transmitter, &AudioTransmitter::error,
            this, &WasapiLoopbackCaptureSimple::onTransmissionError);
    connect(m_transmitter, &AudioTransmitter::dataSent,
            this, &WasapiLoopbackCaptureSimple::onTransmissionDataSent);
    connect(m_transmitter, &AudioTransmitter::connectionEstablished,
            this, &WasapiLoopbackCaptureSimple::onTransmissionConnectionEstablished);
    connect(m_transmitter, &AudioTransmitter::connectionLost,
            this, &WasapiLoopbackCaptureSimple::onTransmissionConnectionLost);
}

WasapiLoopbackCaptureSimple::~WasapiLoopbackCaptureSimple()
{
    stopCapture();
    cleanupWASAPI();
}

bool WasapiLoopbackCaptureSimple::startCapture(const QString &outputFilePath)
{
    if (m_isCapturing) {
        qWarning() << "音频捕获已在运行中";
        return false;
    }
    
    // 检查输出文件路径
    QFileInfo fileInfo(outputFilePath);
    QDir dir = fileInfo.absoluteDir();
    if (!dir.exists()) {
        if (!dir.mkpath(".")) {
            emit captureError("无法创建输出目录");
            return false;
        }
    }
    
    // 初始化WASAPI
    if (!initializeWASAPI()) {
        emit captureError("初始化WASAPI失败");
        return false;
    }
    
    // 设置loopback捕获
    if (!setupLoopbackCapture()) {
        emit captureError("设置loopback捕获失败");
        cleanupWASAPI();
        return false;
    }
    
    // 打开输出文件
    m_outputFilePath = outputFilePath;
    m_outputFile.setFileName(outputFilePath);
    
    if (!m_outputFile.open(QIODevice::WriteOnly)) {
        emit captureError("无法打开输出文件进行写入");
        cleanupWASAPI();
        return false;
    }
    
    // 写入WAV文件头
    writeWavHeader();
    
    // 启动捕获定时器
    m_captureTimer->start(5); // 5ms间隔，高精度捕获，与20ms缓冲区匹配
    
    m_isCapturing = true;
    emit captureStatusChanged(true);
    
    qDebug() << "WASAPI loopback捕获已启动，输出文件:" << outputFilePath;
    return true;
}

void WasapiLoopbackCaptureSimple::stopCapture()
{
    if (!m_isCapturing) {
        return;
    }
    
    qDebug() << "停止WASAPI loopback捕获...";
    
    // 停止捕获定时器
    if (m_captureTimer) {
        m_captureTimer->stop();
    }
    
    // 完成WAV文件
    if (m_outputFile.isOpen()) {
        finalizeWavFile();
        m_outputFile.close();
    }
    
    // 清理WASAPI资源
    cleanupWASAPI();
    
    m_isCapturing = false;
    emit captureStatusChanged(false);
    
    qDebug() << "WASAPI loopback捕获已停止";
}

bool WasapiLoopbackCaptureSimple::initializeWASAPI()
{
    HRESULT hr;
    
    // 初始化COM（如果还没有初始化的话）
    hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
    if (FAILED(hr)) {
        if (hr == RPC_E_CHANGED_MODE) {
            // COM已经在不同的模式下初始化，尝试使用单线程模式
            hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
            if (FAILED(hr)) {
                qWarning() << "COM单线程模式初始化失败:" << hr;
                return false;
            }
        } else if (hr == S_FALSE) {
            // COM已经初始化，继续
            qDebug() << "COM已经初始化";
        } else {
            qWarning() << "COM初始化失败:" << hr;
            return false;
        }
    }
    
    // 创建设备枚举器
    hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_ALL,
                         __uuidof(IMMDeviceEnumerator), (void**)&m_deviceEnumerator);
    if (FAILED(hr)) {
        qWarning() << "创建设备枚举器失败，错误代码:" << hr;
        if (hr == REGDB_E_CLASSNOTREG) {
            qWarning() << "  原因: MMDeviceEnumerator类未注册";
        } else if (hr == E_NOINTERFACE) {
            qWarning() << "  原因: 接口不支持";
        } else if (hr == E_OUTOFMEMORY) {
            qWarning() << "  原因: 内存不足";
        }
        CoUninitialize();
        return false;
    }
    
    // 获取默认音频输出设备
    hr = m_deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &m_audioDevice);
    if (FAILED(hr)) {
        qWarning() << "获取默认音频输出设备失败:" << hr;
        m_deviceEnumerator->Release();
        CoUninitialize();
        return false;
    }
    
    // 创建音频客户端
    hr = m_audioDevice->Activate(__uuidof(IAudioClient), CLSCTX_ALL, nullptr, (void**)&m_audioClient);
    if (FAILED(hr)) {
        qWarning() << "创建音频客户端失败:" << hr;
        m_audioDevice->Release();
        m_deviceEnumerator->Release();
        CoUninitialize();
        return false;
    }
    
    // 获取设备混合格式（推荐用于loopback捕获）
    hr = m_audioClient->GetMixFormat(&m_waveFormat);
    if (SUCCEEDED(hr)) {
        qDebug() << "获取到设备混合格式:"
                 << "采样率:" << m_waveFormat->nSamplesPerSec
                 << "通道数:" << m_waveFormat->nChannels
                 << "位深度:" << m_waveFormat->wBitsPerSample
                 << "格式标签:" << m_waveFormat->wFormatTag;
        
        // 检查格式是否支持，如果不支持则转换为PCM
        if (m_waveFormat->wFormatTag != WAVE_FORMAT_PCM) {
            qDebug() << "检测到非PCM格式，转换为PCM格式";
            
            // 保存原始格式信息
            UINT32 sampleRate = m_waveFormat->nSamplesPerSec;
            UINT16 channels = m_waveFormat->nChannels;
            UINT16 bitsPerSample = m_waveFormat->wBitsPerSample;
            
            // 释放原始格式
            CoTaskMemFree(m_waveFormat);
            
            // 创建PCM格式
            m_waveFormat = (WAVEFORMATEX*)malloc(sizeof(WAVEFORMATEX));
            if (!m_waveFormat) {
                qWarning() << "分配PCM格式内存失败";
                m_audioClient->Release();
                m_audioDevice->Release();
                m_deviceEnumerator->Release();
                CoUninitialize();
                return false;
            }
            
            // 设置PCM格式，使用原始采样率和通道数
            m_waveFormat->wFormatTag = WAVE_FORMAT_PCM;
            m_waveFormat->nChannels = channels;
            m_waveFormat->nSamplesPerSec = sampleRate;
            m_waveFormat->wBitsPerSample = 16; // 强制使用16位PCM
            m_waveFormat->nBlockAlign = (m_waveFormat->nChannels * m_waveFormat->wBitsPerSample) / 8;
            m_waveFormat->nAvgBytesPerSec = m_waveFormat->nSamplesPerSec * m_waveFormat->nBlockAlign;
            m_waveFormat->cbSize = 0;
            
            qDebug() << "转换为PCM格式:"
                     << "采样率:" << m_waveFormat->nSamplesPerSec
                     << "通道数:" << m_waveFormat->nChannels
                     << "位深度:" << m_waveFormat->wBitsPerSample;
        }
    } else {
        qWarning() << "获取混合格式失败，使用默认格式";
        
        // 如果获取混合格式失败，使用默认格式
        m_waveFormat = (WAVEFORMATEX*)malloc(sizeof(WAVEFORMATEX));
        if (!m_waveFormat) {
            qWarning() << "分配音频格式内存失败";
            m_audioClient->Release();
            m_audioDevice->Release();
            m_deviceEnumerator->Release();
            CoUninitialize();
            return false;
        }
        
        // 使用更兼容的音频格式
        m_waveFormat->wFormatTag = WAVE_FORMAT_PCM;
        m_waveFormat->nChannels = 2;  // 立体声
        m_waveFormat->nSamplesPerSec = 48000;  // 48kHz，更兼容
        m_waveFormat->wBitsPerSample = 16;  // 16位
        m_waveFormat->nBlockAlign = (m_waveFormat->nChannels * m_waveFormat->wBitsPerSample) / 8;
        m_waveFormat->nAvgBytesPerSec = m_waveFormat->nSamplesPerSec * m_waveFormat->nBlockAlign;
        m_waveFormat->cbSize = 0;
        
        qDebug() << "使用默认音频格式:"
                 << "采样率:" << m_waveFormat->nSamplesPerSec
                 << "通道数:" << m_waveFormat->nChannels
                 << "位深度:" << m_waveFormat->wBitsPerSample;
    }
    
    // 初始化音频客户端
    qDebug() << "正在初始化音频客户端...";
    qDebug() << "  共享模式: AUDCLNT_SHAREMODE_SHARED";
    qDebug() << "  流标志: AUDCLNT_STREAMFLAGS_LOOPBACK";
    qDebug() << "  缓冲区持续时间:" << BUFFER_DURATION << "ms";
    
    hr = m_audioClient->Initialize(AUDCLNT_SHAREMODE_SHARED,
                                  AUDCLNT_STREAMFLAGS_LOOPBACK, // 使用正确的loopback标志
                                  BUFFER_DURATION * 10000, // 转换为100ns单位
                                  0,
                                  m_waveFormat,
                                  nullptr);
    if (FAILED(hr)) {
        qWarning() << "初始化音频客户端失败，错误代码:" << hr;
        if (hr == AUDCLNT_E_UNSUPPORTED_FORMAT) {
            qWarning() << "  原因: 音频格式不支持";
        } else if (hr == AUDCLNT_E_DEVICE_INVALIDATED) {
            qWarning() << "  原因: 音频设备无效";
        } else if (hr == AUDCLNT_E_DEVICE_IN_USE) {
            qWarning() << "  原因: 音频设备正在使用中";
        } else if (hr == AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED) {
            qWarning() << "  原因: 缓冲区大小未对齐";
        }
        
        CoTaskMemFree(m_waveFormat);
        m_audioClient->Release();
        m_audioDevice->Release();
        m_deviceEnumerator->Release();
        CoUninitialize();
        return false;
    }
    
    qDebug() << "音频客户端初始化成功";
    
    // 获取缓冲区大小
    hr = m_audioClient->GetBufferSize(&m_bufferFrameCount);
    if (FAILED(hr)) {
        qWarning() << "获取缓冲区大小失败:" << hr;
        CoTaskMemFree(m_waveFormat);
        m_audioClient->Release();
        m_audioDevice->Release();
        m_deviceEnumerator->Release();
        CoUninitialize();
        return false;
    }
    
    // 获取捕获客户端
    hr = m_audioClient->GetService(__uuidof(IAudioCaptureClient), (void**)&m_captureClient);
    if (FAILED(hr)) {
        qWarning() << "获取捕获客户端失败，错误代码:" << hr;
        if (hr == AUDCLNT_E_NOT_INITIALIZED) {
            qWarning() << "  原因: 音频客户端未初始化";
        } else if (hr == AUDCLNT_E_UNSUPPORTED_FORMAT) {
            qWarning() << "  原因: 音频格式不支持";
        } else if (hr == AUDCLNT_E_SERVICE_NOT_RUNNING) {
            qWarning() << "  原因: 音频服务未运行";
        } else if (hr == E_NOINTERFACE) {
            qWarning() << "  原因: 接口不支持";
        }
        
        // 尝试获取更详细的错误信息
        qWarning() << "音频客户端状态检查:";
        qWarning() << "  采样率:" << m_waveFormat->nSamplesPerSec;
        qWarning() << "  通道数:" << m_waveFormat->nChannels;
        qWarning() << "  位深度:" << m_waveFormat->wBitsPerSample;
        qWarning() << "  缓冲区大小:" << m_bufferFrameCount;
        
        CoTaskMemFree(m_waveFormat);
        m_audioClient->Release();
        m_audioDevice->Release();
        m_deviceEnumerator->Release();
        CoUninitialize();
        return false;
    }
    
    m_wasapiInitialized = true;
    qDebug() << "WASAPI初始化成功，缓冲区大小:" << m_bufferFrameCount << "帧";
    return true;
}

bool WasapiLoopbackCaptureSimple::setupLoopbackCapture()
{
    if (!m_wasapiInitialized) {
        return false;
    }
    
    // 启动音频客户端
    HRESULT hr = m_audioClient->Start();
    if (FAILED(hr)) {
        qWarning() << "启动音频客户端失败:" << hr;
        return false;
    }
    
    qDebug() << "WASAPI loopback捕获设置完成";
    return true;
}

void WasapiLoopbackCaptureSimple::onCaptureTimer()
{
    if (!m_isCapturing || !m_wasapiInitialized) {
        return;
    }
    
    captureAudioData();
}

void WasapiLoopbackCaptureSimple::captureAudioData()
{
    if (!m_captureClient) {
        return;
    }
    
    HRESULT hr;
    UINT32 packetLength = 0;
    BYTE *data = nullptr;
    UINT32 numFramesAvailable = 0;
    DWORD flags = 0;
    
    // 获取下一个数据包
    hr = m_captureClient->GetNextPacketSize(&packetLength);
    if (FAILED(hr)) {
        return;
    }
    
    while (packetLength > 0) {
        // 获取捕获缓冲区
        hr = m_captureClient->GetBuffer(&data, &numFramesAvailable, &flags, nullptr, nullptr);
        if (SUCCEEDED(hr)) {
            if (numFramesAvailable > 0) {
                // 计算数据大小
                UINT32 dataSize = numFramesAvailable * m_waveFormat->nBlockAlign;
                
                // 检查数据有效性
                if (dataSize > 0 && dataSize < 1024 * 1024) { // 限制在1MB以内
                    // 检查音频数据是否包含静音或异常值
                    bool hasValidData = false;
                    for (UINT32 i = 0; i < dataSize && i < 1000; i += 2) { // 检查前1000个样本
                        if (data[i] != 0 || data[i + 1] != 0) {
                            hasValidData = true;
                            break;
                        }
                    }
                    
                    if (hasValidData) {
                        // 写入文件
                        if (m_outputFile.isOpen()) {
                            m_outputFile.write((char*)data, dataSize);
                            m_outputFile.flush();
                            
                            emit captureProgress(dataSize);
                        }
                        
                        // 发送音频数据到传输器
                        if (m_transmitter && m_transmissionEnabled) {
                            QByteArray audioData((char*)data, dataSize);
                            m_transmitter->sendAudioData(audioData);
                        }
                    } else {
                        qDebug() << "检测到静音数据，跳过写入";
                    }
                } else {
                    qWarning() << "音频数据大小异常:" << dataSize << "字节，跳过";
                }
            }
            
            // 释放缓冲区
            m_captureClient->ReleaseBuffer(numFramesAvailable);
        }
        
        // 获取下一个数据包
        hr = m_captureClient->GetNextPacketSize(&packetLength);
        if (FAILED(hr)) {
            break;
        }
    }
}

void WasapiLoopbackCaptureSimple::writeWavHeader()
{
    if (!m_waveFormat) {
        return;
    }
    
    QDataStream stream(&m_outputFile);
    stream.setByteOrder(QDataStream::LittleEndian);
    
    // RIFF头
    stream.writeRawData("RIFF", 4);
    m_fileSizePosition = m_outputFile.pos();
    stream << quint32(0); // 文件大小占位符
    stream.writeRawData("WAVE", 4);
    
    // fmt子块
    stream.writeRawData("fmt ", 4);
    stream << quint32(16); // fmt子块大小
    stream << quint16(1);  // 音频格式 (PCM)
    stream << quint16(m_waveFormat->nChannels);
    stream << quint32(m_waveFormat->nSamplesPerSec);
    stream << quint32(m_waveFormat->nAvgBytesPerSec);
    stream << quint16(m_waveFormat->nBlockAlign);
    stream << quint16(m_waveFormat->wBitsPerSample);
    
    // data子块
    stream.writeRawData("data", 4);
    m_dataSizePosition = m_outputFile.pos();
    stream << quint32(0); // 数据大小占位符
    
    m_dataStartPosition = m_outputFile.pos();
    
    qDebug() << "WAV文件头写入完成";
}

void WasapiLoopbackCaptureSimple::finalizeWavFile()
{
    if (!m_outputFile.isOpen()) {
        return;
    }
    
    qint64 dataEndPosition = m_outputFile.pos();
    qint64 dataSize = dataEndPosition - m_dataStartPosition;
    qint64 fileSize = dataEndPosition - 8;
    
    // 更新文件大小
    m_outputFile.seek(m_fileSizePosition);
    QDataStream stream(&m_outputFile);
    stream.setByteOrder(QDataStream::LittleEndian);
    stream << quint32(fileSize);
    
    // 更新数据大小
    m_outputFile.seek(m_dataSizePosition);
    stream << quint32(dataSize);
    
    qDebug() << "WAV文件已完成，数据大小:" << dataSize << "字节";
}

void WasapiLoopbackCaptureSimple::cleanupWASAPI()
{
    if (m_captureClient) {
        m_captureClient->Release();
        m_captureClient = nullptr;
    }
    
    if (m_audioClient) {
        m_audioClient->Release();
        m_audioClient = nullptr;
    }
    
    if (m_audioDevice) {
        m_audioDevice->Release();
        m_audioDevice = nullptr;
    }
    
    if (m_deviceEnumerator) {
        m_deviceEnumerator->Release();
        m_deviceEnumerator = nullptr;
    }
    
    if (m_waveFormat) {
        CoTaskMemFree(m_waveFormat);
        m_waveFormat = nullptr;
    }
    
    CoUninitialize();
    m_wasapiInitialized = false;
    
    qDebug() << "WASAPI资源已清理";
}

// 音频传输相关方法实现
bool WasapiLoopbackCaptureSimple::startTransmission(const QString &host, quint16 port)
{
    if (!m_transmitter) {
        qWarning() << "音频传输器未初始化";
        return false;
    }
    
    m_transmissionHost = host;
    m_transmissionPort = port;
    
    // 使用AudioTransmitter的正确方法名
    bool success = m_transmitter->connectToServer(host, port);
    if (success) {
        m_transmissionEnabled = true;
        qDebug() << "音频传输已启动:" << host << ":" << port;
    }
    
    return success;
}

void WasapiLoopbackCaptureSimple::stopTransmission()
{
    if (m_transmitter) {
        m_transmitter->disconnectFromServer();
        m_transmissionEnabled = false;
        qDebug() << "音频传输已停止";
    }
}

void WasapiLoopbackCaptureSimple::setTransmissionEnabled(bool enabled)
{
    if (m_transmitter) {
        m_transmitter->setTransmissionEnabled(enabled);
        m_transmissionEnabled = enabled;
    }
}

void WasapiLoopbackCaptureSimple::setTransmissionHost(const QString &host)
{
    m_transmissionHost = host;
    // AudioTransmitter没有setTransmissionHost方法，需要重新连接
    if (m_transmitter && m_transmissionEnabled) {
        m_transmitter->disconnectFromServer();
        m_transmitter->connectToServer(host, m_transmissionPort);
    }
}

void WasapiLoopbackCaptureSimple::setTransmissionPort(quint16 port)
{
    m_transmissionPort = port;
    // AudioTransmitter没有setTransmissionPort方法，需要重新连接
    if (m_transmitter && m_transmissionEnabled) {
        m_transmitter->disconnectFromServer();
        m_transmitter->connectToServer(m_transmissionHost, port);
    }
}

void WasapiLoopbackCaptureSimple::setTransmissionBufferSize(int size)
{
    if (m_transmitter) {
        m_transmitter->setBufferSize(size);
    }
}

void WasapiLoopbackCaptureSimple::setTransmissionInterval(int intervalMs)
{
    if (m_transmitter) {
        m_transmitter->setTransmissionInterval(intervalMs);
    }
}

void WasapiLoopbackCaptureSimple::setTransmissionCompression(bool enabled)
{
    if (m_transmitter) {
        m_transmitter->setCompressionEnabled(enabled);
    }
}

// 传输相关槽函数实现
void WasapiLoopbackCaptureSimple::onTransmissionStatusChanged(bool enabled)
{
    m_transmissionEnabled = enabled;
    emit transmissionStatusChanged(enabled);
}

void WasapiLoopbackCaptureSimple::onTransmissionError(const QString &error)
{
    emit transmissionError(error);
}

void WasapiLoopbackCaptureSimple::onTransmissionDataSent(qint64 bytesSent)
{
    emit transmissionDataSent(bytesSent);
}

void WasapiLoopbackCaptureSimple::onTransmissionConnectionEstablished()
{
    emit transmissionConnectionEstablished();
}

void WasapiLoopbackCaptureSimple::onTransmissionConnectionLost()
{
    emit transmissionConnectionLost();
}
